home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 October / EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso / Aminet / util / dtype / FontDT_1_0.lha / Src / dispatch.c < prev    next >
C/C++ Source or Header  |  1995-04-22  |  12KB  |  388 lines

  1. /*
  2. **    dispatch.c - dispatcher for Font DataType class
  3. **    Copyright © 1995 Michael Letowski
  4. */
  5.  
  6. #include <exec/types.h>
  7. #include <exec/memory.h>
  8. #include <dos/dos.h>
  9. #include <dos/rdargs.h>
  10. #include <graphics/displayinfo.h>
  11. #include <graphics/gfx.h>
  12. #include <graphics/modeid.h>
  13. #include <graphics/rastport.h>
  14. #include <graphics/text.h>
  15. #include <intuition/classes.h>
  16. #include <datatypes/datatypesclass.h>
  17. #include <datatypes/pictureclass.h>
  18. #include <diskfont/diskfont.h>
  19. #include <diskfont/diskfonttag.h>
  20. #include <utility/hooks.h>
  21. #include <support/types.h>
  22.  
  23. #include <stdlib.h>
  24.  
  25. #include <proto/dos.h>
  26. #include <proto/exec.h>
  27. #include <proto/diskfont.h>
  28. #include <proto/datatypes.h>
  29. #include <proto/graphics.h>
  30. #include <proto/intuition.h>
  31. #include <proto/utility.h>
  32. #include <clib/support_protos.h>
  33.  
  34. #include "classbase.h"
  35. #include "dispatch.h"
  36. #include "prefs.h"
  37. #include "otag.h"
  38.  
  39. #define COL_WHITE                        0xFF
  40. #define COL_BLACK                        0x00
  41.  
  42. #define MAX_CHAR                        257
  43.  
  44. /* Get font's name */
  45. #define FontName(f)    ((f)->tf_Message.mn_Node.ln_Name)
  46.  
  47. typedef int (SFUNC)(void const*, void const *);
  48.  
  49. STATIC ASM Object *Dispatch(R_A0 Class *cl, R_A2 Object *o, R_A1 Msg msg);
  50. STATIC LBOOL GetFont(struct ClassBase *cb, Object *o, struct TagItem *attrs);
  51.  
  52. /* Font management */
  53. STATIC struct TextFont **OpenFonts(struct ClassBase *cb,
  54.                                                                         struct FontContentsHeader *fch, STRPTR name);
  55. STATIC VOID CloseFonts(struct ClassBase *cb, struct TextFont **f, ULONG cnt);
  56. STATIC VOID GetWH(struct ClassBase *cb, struct RastPort *rp, struct Opts *opt,
  57.                                         struct TextFont *f, ULONG *w, ULONG *h);
  58. STATIC VOID Render(struct ClassBase *cb, struct RastPort *rp, struct Opts *opt,
  59.                                         struct TextFont **f, ULONG cnt, ULONG w);
  60. STATIC VOID MakeASCII(struct TextFont *f, CHAR *s);
  61. STATIC VOID MakeFontName(struct TextFont *f, CHAR *s);
  62. STATIC LONG SortFunc(struct TextFont **tf1, struct TextFont **tf2);
  63.  
  64. /* DataTypes stubs */
  65. STATIC ULONG LocSetDTAttrs(struct ClassBase *cb, Object *o, ULONG data, ...);
  66. STATIC ULONG LocGetDTAttrs(struct ClassBase *cb, Object *o, ULONG data, ...);
  67.  
  68. Class *InitClass(struct ClassBase *cb)
  69. {
  70.     Class *CL;
  71.  
  72.     /* Create our class (no instance) */
  73.     if(CL=MakeClass(FONTDTCLASS,PICTUREDTCLASS,NULL,NULL,0))
  74.     {
  75.         CL->cl_Dispatcher.h_Entry=(HOOKFUNC)Dispatch;
  76.         CL->cl_UserData=(ULONG)cb;
  77.         AddClass(CL);
  78.     }
  79.     return(CL);
  80. }    /* InitClass */
  81.  
  82. STATIC ASM Object *Dispatch(R_A0 Class *cl, R_A2 Object *o, R_A1 Msg msg)
  83. {
  84.     struct ClassBase *cb=(struct ClassBase *)cl->cl_UserData;
  85.     Object *Obj;
  86.  
  87.     switch(msg->MethodID)
  88.     {
  89.         case OM_NEW:                                                                /* We know this method */
  90.             if(Obj=(Object *)DoSuperMethodA(cl,o,msg))
  91.                 unless(GetFont(cb,Obj,((struct opSet *)msg)->ops_AttrList))
  92.                 {
  93.                     CoerceMethod(cl,Obj,OM_DISPOSE);
  94.                     return(NULL);
  95.                 }
  96.             break;
  97.         default:                                                                        /* Let the superclass handle it */
  98.             Obj=(Object *)DoSuperMethodA(cl,o,msg);
  99.             break;
  100.     }
  101.     return(Obj);
  102. }
  103.  
  104. STATIC LBOOL GetFont(struct ClassBase *cb, Object *o, struct TagItem *attrs)
  105. {
  106.     struct RastPort RP;
  107.     struct Opts Opts;
  108.     struct BitMapHeader *BMHD=NULL;
  109.     struct BitMap *BM;
  110.     struct ColorRegister *CMap=NULL;
  111.     LONG *CRegs=NULL;
  112.     struct FileInfoBlock *FIB;
  113.     struct FontContentsHeader *FCH;
  114.     struct TextFont **Fonts,*F;
  115.     struct ColorTextFont *CF;
  116.     struct ColorFontColors *CFC;
  117.     struct PrefsHandle *PH;
  118.  
  119.     STRPTR Name=NULL,Title;                                                /* Font file name & picture title */
  120.     BPTR DirLock,FH=0;
  121.     ULONG ModeID,SourceID;                                                /* Display mode */
  122.     ULONG Width,Height,Depth,NumColors;
  123.     ULONG I,J,NumFonts;
  124.     LBOOL Tall,Wide,Result=FALSE;
  125.     UBYTE Col0,Col1;
  126.  
  127.     /* Get default title */
  128.     Title=(STRPTR)GetTagData(DTA_Name,NULL,attrs);
  129.  
  130.     /* Get file handle and BitMapHeader */
  131.     LocGetDTAttrs(cb,o,DTA_Handle,&FH,PDTA_BitMapHeader,&BMHD,TAG_DONE);
  132.     try(FH && BMHD,    EXIT);
  133.  
  134.     /* Get font file name */
  135.     try(FIB=AllocDosObject(DOS_FIB,NULL),    NO_FIB);/* Create FileInfoBlock */
  136.     if(ExamineFH(FH,FIB))                                                    /* Examine it */
  137.         Name=FIB->fib_FileName;                                            /* Get name pointer */
  138.     else
  139.         if(Title)                                                                        /* Get file part of title */
  140.             Name=FilePart(Title);
  141.     try(Name,    NO_NAME);
  142.  
  143.     /* Get font */
  144.     try(DirLock=ParentOfFH(FH),                NO_LOCK);
  145.     try(FCH=NewFC(cb,DirLock,Name),        NO_FCH);
  146.     try(Fonts=OpenFonts(cb,FCH,Name),    NO_FONTS);
  147.     NumFonts=FCH->fch_NumEntries;
  148.  
  149.     /* Read preferences */
  150.     PH=GetFontPrefs(cb,&Opts);
  151.  
  152.     /* Calculate sizes */
  153.     Width=Height=0;
  154.     Depth=1;
  155.     InitRastPort(&RP);                                                        /* Set up RastPort - here! */
  156.     for(I=0; I<NumFonts; I++)
  157.         if(F=Fonts[I])                                                            /* Opened successfully */
  158.         {
  159.             GetWH(cb,&RP,&Opts,F,&Width,&Height);            /* Get width and height */
  160.             if(ftst(F->tf_Style,FSF_COLORFONT))                /* This is ColorFont */
  161.             {
  162.                 CF=(struct ColorTextFont *)F;
  163.                 if(CF->ctf_Depth>Depth)                                    /* Deeper? */
  164.                     Depth=CF->ctf_Depth;                                    /* Set new depth */
  165.             }
  166.             Tall=ftst(F->tf_Flags,FPF_TALLDOT);                /* Hires? */
  167.             Wide=ftst(F->tf_Flags,FPF_WIDEDOT);                /* Interlaced? */
  168.         }
  169.  
  170.     /* Set up BitMap header */
  171.     BMHD->bmh_Width=Width;                                                /* Fill in informations */
  172.     BMHD->bmh_Height=Height;
  173.     BMHD->bmh_Depth=Depth;
  174.     NumColors=1<<Depth;
  175.  
  176.     /* Get display mode id */
  177.     if(Tall && Wide)    SourceID=HIRESLACE_KEY;
  178.     else if(Tall)            SourceID=HIRES_KEY;
  179.     else if(Wide)            SourceID=LORESLACE_KEY;
  180.     else                            SourceID=LORES_KEY;
  181.     ModeID=BestModeID(BIDTAG_DesiredWidth,    Width,
  182.                                         BIDTAG_DesiredHeight,    Height,
  183.                                         BIDTAG_Depth,                    Depth,
  184.                                         BIDTAG_SourceID,            SourceID,
  185.                                         TAG_DONE);
  186.  
  187.     /* Set colors */
  188.     LocSetDTAttrs(cb,o,PDTA_NumColors,NumColors,TAG_DONE);
  189.     LocGetDTAttrs(cb,o,PDTA_ColorRegisters,&CMap,PDTA_CRegs,&CRegs,TAG_DONE);
  190.     try(CMap && CRegs,    ERROR);
  191.     if(Depth==1)                                                                    /* B&W font */
  192.     {
  193.         Col0=Opts.opt_Inverse ? COL_BLACK : COL_WHITE;
  194.         Col1=Opts.opt_Inverse ? COL_WHITE : COL_BLACK;
  195.         CMap[0].red=CMap[0].green=CMap[0].blue=Col0;
  196.         CMap[1].red=CMap[1].green=CMap[1].blue=Col1;
  197.         CRegs[0]=CRegs[1]=CRegs[2]=Col0<<24;
  198.         CRegs[3]=CRegs[4]=CRegs[5]=Col1<<24;
  199.     }
  200.     else                                                                                    /* Some color fonts */
  201.         for(I=0; I<NumFonts; I++)
  202.             if(F=Fonts[I])
  203.                 if(ftst(F->tf_Style,FSF_COLORFONT))
  204.                 {
  205.                     CF=(struct ColorTextFont *)F;
  206.                     if(CFC=CF->ctf_ColorFontColors)                        /* Color map exists */
  207.                         for(J=0; J<CFC->cfc_Count; J++)
  208.                         {
  209.                             CMap[J].red=        (CFC->cfc_ColorTable[J] & 0x0F00)>>4;
  210.                             CRegs[J*3+0]=        CMap[J].red<<24;
  211.                             CMap[J].green=    (CFC->cfc_ColorTable[J] & 0x00F0);
  212.                             CRegs[J*3+1]=        CMap[J].green<<24;
  213.                             CMap[J].blue=        (CFC->cfc_ColorTable[J] & 0x000F)<<4;
  214.                             CRegs[J*3+2]=        CMap[J].blue<<24;
  215.                         }
  216.                 }
  217.  
  218.     /* Prepare bitmap */
  219.     try(BM=AllocBitMap(BMHD->bmh_Width,BMHD->bmh_Height,BMHD->bmh_Depth,
  220.                                             BMF_CLEAR | BMF_INTERLEAVED,NULL),
  221.             ERROR);
  222.  
  223.     /* Do rendering */
  224.     RP.BitMap=BM;                                                                    /* Attach BitMap */
  225.     Render(cb,&RP,&Opts,Fonts,NumFonts,Width);
  226.  
  227.     /* Set attributes of destination picture */
  228.     LocSetDTAttrs(cb,o,DTA_ObjName,                Title,
  229.                                             DTA_NominalHoriz,    BMHD->bmh_Width,
  230.                                             DTA_NominalVert,    BMHD->bmh_Height,
  231.                                             PDTA_BitMap,            BM,
  232.                                             PDTA_ModeID,            ModeID,
  233.                                             TAG_DONE);
  234.     Result=TRUE;
  235.  
  236.     /* Cleanup */
  237.     except(ERROR,            );
  238.     if(PH)
  239.         FreeFontPrefs(cb,PH);
  240.     except(NO_FONTS,    CloseFonts(cb,Fonts,NumFonts));
  241.     except(NO_FCH,        DisposeFC(cb,FCH));
  242.     except(NO_LOCK,        UnLock(DirLock));
  243.     except(NO_NAME,        );
  244.     except(NO_FIB,        FreeDosObject(DOS_FIB,FIB));
  245.     except(EXIT,            );
  246.     return(Result);
  247. }    /* GetFont */
  248.  
  249. /****************************************************************************/
  250. /*                             Font management                              */
  251. /****************************************************************************/
  252.  
  253. STATIC struct TextFont **OpenFonts(struct ClassBase *cb,
  254.                                                                         struct FontContentsHeader *fch, STRPTR name)
  255. {
  256.     struct TextFont **Fonts;
  257.     struct TFontContents *TFC;
  258.     struct TTextAttr TTA;
  259.     ULONG I,NumEntries=fch->fch_NumEntries;
  260.     LBOOL One=FALSE;                                                            /* Got at least one size */
  261.  
  262.     try(Fonts=AllocVec(NumEntries*sizeof(APTR),MEMF_CLEAR),    NO_FONTS);
  263.     for(I=0; I<NumEntries; I++)
  264.     {
  265.         TFC=&TFontContents(fch)[I];                                /* Get FontContents */
  266.         TTA.tta_Name=name;                                                /* Copy attrs */
  267.         TTA.tta_YSize=TFC->tfc_YSize;
  268.         TTA.tta_Style=TFC->tfc_Style;
  269.         TTA.tta_Flags=TFC->tfc_Flags;
  270.         if(ftst(TFC->tfc_Style,FSF_TAGGED))                /* Tags should be set */
  271.             TTA.tta_Tags=(struct TagItem *)
  272.                                         &TFC->tfc_FileName
  273.                                             [MAXFONTPATH-(TFC->tfc_TagCount*sizeof(struct TagItem))];
  274.         if(Fonts[I]=OpenDiskFont((struct TextAttr *)&TTA))
  275.             One=TRUE;
  276.     }
  277.     if(One)                                                                                /* Got at least one font */
  278.     {                                                                                            /* Sort by size */
  279.         qsort(Fonts,NumEntries,sizeof(APTR),(SFUNC *)SortFunc);
  280.         return(Fonts);
  281.     }
  282.     else
  283.         SetIoErr(ERROR_OBJECT_NOT_FOUND);                        /* Set error */
  284.  
  285.     except(NO_FONTS,    FreeVec(Fonts));
  286.     return(NULL);
  287. }    /* OpenFonts */
  288.  
  289. STATIC VOID CloseFonts(struct ClassBase *cb, struct TextFont **f, ULONG cnt)
  290. {
  291.     ULONG I;
  292.  
  293.     for(I=0; I<cnt; I++)
  294.         if(f[I])
  295.             CloseFont(f[I]);
  296.     FreeVec(f);
  297. }    /* CloseFonts */
  298.  
  299. STATIC VOID GetWH(struct ClassBase *cb, struct RastPort *rp, struct Opts *opt,
  300.                                         struct TextFont *f, ULONG *w, ULONG *h)
  301. {
  302.     STRPTR DefStrings[]={NULL,NULL};
  303.     STRPTR CurStr,*Strings;
  304.     CHAR S[MAX_CHAR];
  305.     ULONG W;
  306.  
  307.     SetFont(rp,f);
  308.     DefStrings[0]=S;
  309.     if(opt->opt_FontName && FontName(f))
  310.         MakeFontName(f,S);                                                    /* String=name+size */
  311.     else
  312.         MakeASCII(f,S);                                                            /* Prepare default string */
  313.     Strings=opt->opt_Strings ? opt->opt_Strings : DefStrings;
  314.     while(CurStr=*Strings++)
  315.     {
  316.         W=TextLength(rp,CurStr,strlen(CurStr));            /* Calculate len of this line */
  317.         if(W>*w)                                                                        /* If larger... */
  318.             *w=W;                                                                            /* Make it new width */
  319.         *h+=f->tf_YSize;                                                        /* Add to height */
  320.     }
  321. }    /* GetWidth */
  322.  
  323. STATIC VOID Render(struct ClassBase *cb, struct RastPort *rp, struct Opts *opt,
  324.                                         struct TextFont **f, ULONG cnt, ULONG w)
  325. {
  326.     struct TextFont *F;
  327.     STRPTR DefStrings[]={NULL,NULL};
  328.     STRPTR CurStr,*Strings;
  329.     CHAR S[MAX_CHAR];
  330.     ULONG I,X,Y=0;
  331.  
  332.     DefStrings[0]=S;
  333.     for(I=0; I<cnt; I++)                                                    /* For each font size */
  334.         if(F=f[I])                                                                    /* Size opened? */
  335.         {
  336.             SetFont(rp,F);                                                        /* Make it current font */
  337.             if(opt->opt_FontName && FontName(F))
  338.                 MakeFontName(F,S);                                            /* Prepare name+size */
  339.             else
  340.                 MakeASCII(F,S);                                                    /* Prepare default string */
  341.             Strings=opt->opt_Strings ? opt->opt_Strings : DefStrings;
  342.  
  343.             while(CurStr=*Strings++)
  344.             {
  345.                 X=opt->opt_Center ? (w-TextLength(rp,CurStr,strlen(CurStr)))/2 : 0;
  346.                 Move(rp,X,Y+F->tf_Baseline);
  347.                 Text(rp,CurStr,strlen(CurStr));
  348.                 Y+=F->tf_YSize;
  349.             }
  350.         }
  351. }    /* Render */
  352.  
  353. STATIC VOID MakeASCII(struct TextFont *f, CHAR *s)
  354. {
  355.     ULONG I;
  356.  
  357.     memset(s,0,MAX_CHAR);                                                    /* Clear string */
  358.     for(I=f->tf_LoChar; I<=f->tf_HiChar; I++)
  359.         s[I - f->tf_LoChar]=I;                                            /* Make ASCII array */
  360. }    /* MakeASCII */
  361.  
  362. STATIC VOID MakeFontName(struct TextFont *f, CHAR *s)
  363. {
  364.     SNPrintf(s,MAX_CHAR-1,"%s %ld",FontName(f),f->tf_YSize);
  365. }    /* MakeASCII */
  366.  
  367. STATIC LONG SortFunc(struct TextFont **tf1, struct TextFont **tf2)
  368. {
  369.     if(*tf1 && *tf2)    return((LONG)(*tf1)->tf_YSize - (*tf2)->tf_YSize);
  370.     else if(*tf1)            return(-1);
  371.     else if(*tf2)            return(1);
  372.     else                            return(0);
  373. }    /* SortFunc */
  374.  
  375. /****************************************************************************/
  376. /*                             DataTypes stubs                              */
  377. /****************************************************************************/
  378.  
  379. STATIC ULONG LocSetDTAttrs(struct ClassBase *cb, Object *o, ULONG data, ...)
  380. {
  381.     return(SetDTAttrsA(o,NULL,NULL,(struct TagItem *)&data));
  382. }    /* LocSetDTAttrs */
  383.  
  384. STATIC ULONG LocGetDTAttrs(struct ClassBase *cb, Object *o, ULONG data, ...)
  385. {
  386.     return(GetDTAttrsA(o,(struct TagItem *)&data));
  387. }    /* LocGetDTAttrs */
  388.